#ifndef PORTMACRO_H
#define PORTMACRO_H

#include "stdint.h"
#include "stddef.h"
#include "FreeRTOSConfig.h"

/* 数据类型重定义 */
#define portCHAR                char
#define portFLOAT               float
#define portDOUBLE              double
#define portLONG                long
#define portSHORT               short
#define portSTACK_TYPE          uint32_t
#define portBASE_TYPE           long
	
typedef portSTACK_TYPE          StackType_t;
typedef long                    BaseType_t;
typedef unsigned long           UBaseType_t;

/* 由宏 configUSE_16_BIT_TICKS 决定 TickType_t 的具体类型 */
#if( configUSE_16_BIT_TICKS == 1)
typedef uint16_t TickType_t;
#define portMAX_DELAY           (TickType_t) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY           (TickType_t) 0xffffffffUL
#endif

/* 中断控制状态寄存器：0xe000ed04
 * Bit 28 PENDSVSET: PendSV 悬起位
 */
#define portNVIC_INT_CTRL_REG      (*(( volatile uint32_t *) 0xe000ed04))
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )

#define portSY_FULL_READ_WRITE ( 15 )

#define portINLINE __inline

#ifndef portFORCE_INLINE
	#define portFORCE_INLINE __forceinline
#endif

/*
*************************************************************************
*                               宏函数
*************************************************************************
*/

/* 临界区 */
#define portENTER_CRITICAL()  vPortEnterCritical()
#define portEXIT_CRITICAL()  vPortExitCritical()

/* 关中断 */
#define portDISABLE_INTERRUPTS()  vPortRaiseBASEPRI()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)  vPortSetBASEPRI(x)

/* 开中断*/
#define portENABLE_INTERRUPTS()  vPortSetBASEPRI( 0 )
#define portSET_INTERRUPT_MASK_FROM_ISR()  ulPortRaiseBASEPRI()

/* 任务切换 */
#define portYIELD()                                                                   \
{                                                                                     \
    /* 触发 PendSV，产生上下文切换, 中断控制状态寄存器 的 第 28 位置设置为 1 */           \
    /* 当没有其他中断运行的时候响应 PendSV 中断, 去执行我们写好的 PendSV 中断服务函数 */  \
    /* 中断服务函数里面实现任务的切换 */                                                \
    portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;                                   \
    __dsb( portSY_FULL_READ_WRITE );                                                  \
    __isb( portSY_FULL_READ_WRITE );                                                  \
}

#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )

/* 优先级位图管理 */
/* 在 第二种 方法中, uxReadyPriorities 是一位图, 此函数将 uxReadyPriorities 的 uxPriority 位置 置1 */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )\
        ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )

/* 在 第二种 方法中, uxReadyPriorities 是一位图, 此函数将 uxReadyPriorities 的 uxPriority 位置 置0 */
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities )\
        ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )

/* 在 第二种 方法中, 使用前导零指令, 计算位图 uxReadyPriorities 记录的最高优先级变量 */
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )\
        uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) )

/*
*************************************************************************
*                               静态函数
*************************************************************************
*/

/* 关中断: 非中断版本 */
static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
  uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
  
  __asm
  {
    msr basepri, ulNewBASEPRI
    dsb
    isb
  }
}

/* 关中断: 中断版本*/
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{
  uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
  
  __asm
  {
    /* 将 BASEPRI 寄存器内容读取到 ulReturn 文件中 */
    mrs ulReturn, basepri
      
    /* 将 configMAX_SYSCALL_INTERRUPT_PRIORITY 宏设置到 basepri*/
    msr basepri, ulNewBASEPRI
      
    dsb
    isb
  }
  
  return ulReturn;
}

/* 开中断: 全开*/
static portFORCE_INLINE void vPortClearBASEPRIFromISR( void )
{
	__asm
	{
		/* Set BASEPRI to 0 so no interrupts are masked.  This function is only
		used to lower the mask in an interrupt, so memory barriers are not 
		used. */
		msr basepri, #0
	}
}

/* 开中断 */
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
  __asm
  {
    msr basepri, ulBASEPRI
  }
}


/*
*************************************************************************
*                               函数声明
*************************************************************************
*/
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );

#endif
